import { MapData, type FeatureDataInterface, type FeatureInterface, type MapDataInterface } from "@/class/map/MapData";

import { convert_gcj02_To_Gps84, convert_gps84_To_Gcj02, MapCoordSys } from "@/class/map/myMapOpt";
import { reqConvertGps84ToGcj02, reqDeleteMapData } from "@/api/mapdata";
import { reqPostPolygon, reqPutPolygon } from "@/api/polygon";
import { requestIsSuccess } from "@/api/request";
import { getRandomColor, getUUID, toJson } from "@/utils/utils";


export class PolygonData implements FeatureDataInterface {
    featureData: MapDataInterface;
    featureMap: Polygon;
    constructor({ featureData, featureMap }: {
        featureData: MapDataInterface;
        featureMap: Polygon;
    }) {
        this.featureData = new MapData(featureData)
        this.featureMap = new Polygon(featureMap)
    }

    /**
     * 移动到该要素
     * @param map
     */
    moveTo(map:AMap.Map) {
        const element = this.getDateInMap(map)
        var bounds = element.getBounds();
        map.setBounds(bounds)
        this.blinkData(map)
        /*        const path = this.polygon.path
                const getBound = getBounds();
                const result =getBound(path);
                const bounds = new AMap.Bounds(result.southWest,result.northEast);
                map.setBounds(bounds,false,[0,0,0,0])*/
    }


    /**
     * 添加要素，并返回地图要素
     * @param map
     * @returns {*}
     * 每个多边形都要有一个额外的数组包裹，给 path 定义为这种：
     * path:[
     * [
     * [
     * [116.453322, 39.920255],
     * [116.460703, 39.897555],
     * [116.452292, 39.892353],
     * [116.439846, 39.891365]
     * ]
     * ],
     * [
     * [
     * [116.403322, 39.920255],
     * [116.410703, 39.897555],
     * [116.402292, 39.892353],
     * [116.389846, 39.891365]
     * ]
     * ]
     *
     * ]
     */
    addToMap(map:AMap.Map, mapCoordSys:MapCoordSys) {
        if (this.featureData.id === undefined) {
            this.featureData.id = getUUID();
        }
        if (this.featureMap.id === undefined) {
            this.featureMap.id = getUUID();
        }
        const result = this.getBaiduMapOpt(mapCoordSys)
        let feature
        //判断，如果时多个多边形，每个多边形多加一层[],正确加载[[[[1,2],[3,4],[4,5]]],[[[6,7],[8,9],[10,11]]]]
        if (result.path.length > 1//判断是否为多面
            && Array.isArray(result.path[0])//多面第一层为数组
            && Array.isArray(result.path[0][0])//多面第二层为数组
            && !Array.isArray(result.path[0][0][0])//多面的第三层为坐标值[[[1,2],...],...]需要加一层嵌套
        ) {
            // console.log("add []",this.mapData.name,this.polygon.path,result.path)
            for (let i = 0; i < result.path.length; i++) {
                result.path[i] = [result.path[i]]
            }
        }
        feature = new AMap.Polygon(result);
        feature.setExtData({
            id: this.featureData.id,
            name:this.featureData.name,
        })
        map.add(feature)
        /*        const lineFeatureByPolygon = new AMap[MyMapOpt.MapType.Polyline](result)
                map.add(lineFeatureByPolygon)*/
        return feature
    }

    /**
     * 返回地图需要的数据，如果坐标不是CJ02，转换为CJ02
     * @returns {Promise<any>}
     */
    getBaiduMapOpt(mapCoordSys:MapCoordSys) {
        const opt = JSON.parse(JSON.stringify(this.featureMap))
        //坐标转换
        switch (mapCoordSys) {
            case MapCoordSys.CJ02:
                if (this.featureData.coordsys !== MapCoordSys.CJ02)
                    opt.path = convert_gps84_To_Gcj02(opt.path)
                break;
            case MapCoordSys.GPS:
                if (this.featureData.coordsys !== MapCoordSys.GPS)
                    opt.path = convert_gcj02_To_Gps84(opt.path)
                break;
        }
        return opt
    }

    /**
     * 更新面数据
     * @returns true;false
     */
    async update() {
        const result = await reqPutPolygon(this)
        return true
    }

    /**
     * 添加面数据
     * @returns true;false
     */
    async upload() {
        const result = await reqPostPolygon(this)
        return true
    }
    /**
     * 返回要素的原始设置
     * @returns {Marker}
     */
    getElement() {
        return this.featureMap
    }
    /**
     * 判断能否正确添加到该地图
     * @returns {boolean}
     */
    isElement() {
        return (this.featureMap.path as []).length > 0
    }
    /**
     * 返回复制对象
     * @returns {MarkerData}
     */
    getCopy() {
        return new PolygonData(JSON.parse(JSON.stringify(this)))
    }
    /**
     * 返回地图中的对象
     * @param map
     * @returns {*}
     */
    getDateInMap(map:AMap.Map) {
        return map.getAllOverlays().find((item:any) => {
            const flag = item.getOptions().extData.id === this.featureData.id
            return flag
        })
    }
    /**
     * 删除map中的元素
     * @param map
     */
    deleteDataInMap(map:AMap.Map) {
        map.remove(this.getDateInMap(map))
    }
    /**
     * 闪烁该要素
     * @param map
     */
    blinkData(map:AMap.Map) {
        var mapData = this.getDateInMap(map);
        //闪烁次数
        let blinkTimes = 6
        let currentTimes = 0
        //当前透明度
        const fillOpacity = mapData.getOptions().fillOpacity
        const interval = setInterval(() => {
            if (currentTimes < blinkTimes) {
                if (mapData.getOptions().fillOpacity > 0.5) {
                    mapData.setOptions({
                        "fillOpacity": 0
                    })
                } else {
                    mapData.setOptions({
                        "fillOpacity": 1
                    })
                }
                currentTimes++
            } else {
                clearInterval(interval)
                mapData.setOptions({
                    "fillOpacity": fillOpacity
                })
            }
        }, 100)
    }

    /**
     * 下载json数据
     */
    getJSON() {
        toJson(this.featureData.name as string, this)
    }

    /**
     * 删除要素
     */
    deleteElement() {
        return reqDeleteMapData(this.featureData.id as string)
    }
    /**
     * 设置坐标点
     * @param path 坐标点
     * @returns 
     */
    setPath(path:any[]){
        this.featureMap.path=path
     }
}
export class Polygon implements FeatureInterface {
    id?: string
    fillColor?: string
    strokeColor?: string
    fillOpacity?: number
    path?: any[]
    extData?: any
    constructor({ id, fillColor, strokeColor, fillOpacity, path, extData }: {
        id?: string
        fillColor?: string
        strokeColor?: string
        fillOpacity?: number
        path?: any[]
        extData?: any
    }) {
        this.id = id
        this.fillColor = fillColor || getRandomColor()
        this.strokeColor = strokeColor || getRandomColor()
        this.fillOpacity = fillOpacity || 0.5
        this.path = path
        this.extData = extData
    }
}